package com.mixed.mixedserver.game.state;

import com.mixed.mixedserver.game.entity.GameMessage;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Service
public class GameStateService {
    private static final Logger logger = LoggerFactory.getLogger(GameStateService.class);
    private static final String PLAYER_STATE_PREFIX = "game:player:";
    private static final String WORLD_STATE_KEY = "game:world:state";
    private static final long PLAYER_STATE_TTL = 300; // 5分钟TTL
    
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    
    // 内存中的玩家状态缓存
    private final Map<String, GameMessage.PlayerData> playerStates = new ConcurrentHashMap<>();
    
    /**
     * 更新玩家状态
     */
    public void updatePlayerState(String playerId, GameMessage.PlayerData playerData) {
        try {
            // 更新内存缓存
            playerStates.put(playerId, playerData);
            
            // 更新Redis
            String key = PLAYER_STATE_PREFIX + playerId;
            redisTemplate.opsForValue().set(key, playerData, PLAYER_STATE_TTL, TimeUnit.SECONDS);
            
            logger.debug("Updated player state for {}", playerId);
        } catch (Exception e) {
            logger.error("Failed to update player state for {}", playerId, e);
        }
    }
    
    /**
     * 获取玩家状态
     */
    public GameMessage.PlayerData getPlayerState(String playerId) {
        try {
            // 先从内存缓存获取
            GameMessage.PlayerData playerData = playerStates.get(playerId);
            if (playerData != null) {
                return playerData;
            }
            
            // 从Redis获取
            String key = PLAYER_STATE_PREFIX + playerId;
            playerData = (GameMessage.PlayerData) redisTemplate.opsForValue().get(key);
            
            if (playerData != null) {
                // 更新内存缓存
                playerStates.put(playerId, playerData);
            }
            
            return playerData;
        } catch (Exception e) {
            logger.error("Failed to get player state for {}", playerId, e);
            return null;
        }
    }
    
    /**
     * 移除玩家状态
     */
    public void removePlayerState(String playerId) {
        try {
            // 从内存缓存移除
            playerStates.remove(playerId);
            
            // 从Redis移除
            String key = PLAYER_STATE_PREFIX + playerId;
            redisTemplate.delete(key);
            
            logger.debug("Removed player state for {}", playerId);
        } catch (Exception e) {
            logger.error("Failed to remove player state for {}", playerId, e);
        }
    }
    
    /**
     * 获取所有在线玩家状态
     */
    public Map<String, GameMessage.PlayerData> getAllPlayerStates() {
        return new ConcurrentHashMap<>(playerStates);
    }
    
    /**
     * 更新玩家位置
     */
    public void updatePlayerPosition(String playerId, GameMessage.Position position) {
        GameMessage.PlayerData playerData = getPlayerState(playerId);
        if (playerData == null) {
            playerData = new GameMessage.PlayerData();
        }
        
        playerData.setPosition(position);
        updatePlayerState(playerId, playerData);
    }
    
    /**
     * 更新玩家旋转
     */
    public void updatePlayerRotation(String playerId, GameMessage.Rotation rotation) {
        GameMessage.PlayerData playerData = getPlayerState(playerId);
        if (playerData == null) {
            playerData = new GameMessage.PlayerData();
        }
        
        playerData.setRotation(rotation);
        updatePlayerState(playerId, playerData);
    }
    
    /**
     * 更新玩家速度
     */
    public void updatePlayerVelocity(String playerId, GameMessage.Position velocity) {
        GameMessage.PlayerData playerData = getPlayerState(playerId);
        if (playerData == null) {
            playerData = new GameMessage.PlayerData();
        }
        
        playerData.setVelocity(velocity);
        updatePlayerState(playerId, playerData);
    }
    
    /**
     * 检查位置是否在世界边界内
     */
    public boolean isPositionValid(GameMessage.Position position) {
        // 这里可以从配置文件读取世界边界
        float worldWidth = 1000.0f;
        float worldHeight = 1000.0f;
        float worldDepth = 1000.0f;
        
        return position.getX() >= -worldWidth/2 && position.getX() <= worldWidth/2 &&
               position.getY() >= 0 && position.getY() <= worldHeight &&
               position.getZ() >= -worldDepth/2 && position.getZ() <= worldDepth/2;
    }
    
    /**
     * 获取在线玩家数量
     */
    public int getOnlinePlayerCount() {
        return playerStates.size();
    }
    
    /**
     * 清理过期的玩家状态
     */
    public void cleanupExpiredStates() {
        try {
            // 这里可以实现更复杂的清理逻辑
            // 比如检查玩家最后活动时间等
            logger.debug("Cleanup expired states completed");
        } catch (Exception e) {
            logger.error("Failed to cleanup expired states", e);
        }
    }
}